package com.nulldev.util.scripting.ScriptAPI.baseJS.cupJS.parser;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import com.nulldev.util.VariableAPI.StringsUtil;
import com.nulldev.util.data.Variables;
import com.nulldev.util.scripting.ScriptAPI.baseJS.cupJS.util.ReadAheadBufferedReader;
import com.nulldev.util.scripting.ScriptAPI.baseJS.legacy.lexer.BaseJSEnvironment;

public class CUPParser {

	public static BaseJSEnvironment parse(final String payload) {
		Variables.requireNonNull(payload, "payload");
		if (StringsUtil.isBlank(payload))
			return new BaseJSEnvironment();
		final BaseJSEnvironment be = new BaseJSEnvironment();
		__process_payload_string(payload, be);
		return be;
	}

	private static final int EOF = -1;
	private static final int LF = '\r';
	private static final int NL = '\n';
	private static final int SC = ';';

	private static void __process_payload_string(final String str, final BaseJSEnvironment be) {
		final StringBuffer buf = new StringBuffer();
		final Reader r = new ReadAheadBufferedReader(new StringReader(str));
		try {
			__main_loop: {
				while (true) {
					int c;
					__read_loop: {
						while ((c = r.read()) != EOF) {
							if (c == NL)
								break __read_loop;
							if (c == LF) {
								r.mark(1);
								final boolean isNL = r.read() == NL;
								r.reset();
								if (isNL)
									break __read_loop;
							}
							if (c == SC)
								break __read_loop;
							buf.append((char) c);
						}
					}
					CUPDecoder.processPayloadSegment(buf.toString(), be);
					buf.setLength(0);
					if (c == EOF)
						break __main_loop;
				}
			}
		} catch (IOException ex) {
			throw new RuntimeException(ex);
		}
	}
}
